home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
351-375
/
disk_351
/
pdc
/
libsrc.lzh
/
LibSrc
/
StdIO
/
format.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-04-07
|
6KB
|
276 lines
/*
* Libraries and headers for PDC release 3.3 (C) 1989 Lionel Hummel.
* PDC Software Distribution (C) 1989 Lionel Hummel and Paul Petersen.
* PDC I/O Library (C) 1987 by J.A. Lydiatt.
*
* This code is freely redistributable upon the conditions that this
* notice remains intact and that modified versions of this file not
* be included as part of the PDC Software Distribution without the
* express consent of the copyright holders. No warrantee of any
* kind is provided with this code. For further information, contact:
*
* PDC Software Distribution Internet: BIX:
* P.O. Box 4006 or hummel@cs.uiuc.edu lhummel
* Urbana, IL 61801-8801 petersen@uicsrd.csrd.uiuc.edu
*/
/* format.c - routines for generating formatted strings
*
* format - formats a string and outputs character
*/
#include <limits.h>
static unsigned int base;
static int minwidth, precision, padchar, rjust, nsent;
static int (*put)();
/*
* putint: convert long to ascii. Return a pointer to start of string.
*/
static char digit[] = "0123456789ABCDEF";
static char *
putint( str, n)
char *str;
long n;
{
char *s;
int is_negative;
unsigned int un;
if (n == 0x80000000) { /* special case */
switch (base) {
case 8:
s = "20000000000";
break;
case 10:
s = "-2147483648";
break;
case 16:
s = "80000000";
break;
default:
s = "-OOPS-";
}
return s;
}
is_negative = ( base==10 && n<0 );
if ( is_negative )
n = -n;
un = (unsigned int) n;
s = &str[MAXSTRING];
*--s = '\0';
do {
*--s = digit[ un % base ];
un /= base;
}
while ( un && s > &str[1] );
if ( is_negative )
*--s = '-';
return s;
}
/*
* prt: Does the justification and fill if required.
* Side Effects: updates nsent, destroys minwidth.
*/
static int
prt( strbuf )
char *strbuf;
{
extern int strlen();
int i;
int c;
int len = 1;
int strsize = strlen( strbuf );
if ( strsize > precision )
strsize = precision;
if ( rjust ) {
if ( padchar != ' ' && (c = *strbuf) == '-' || c == '+' ) {
if ( (*put)(c) == -1 )
return -1;
++len;
++strbuf;
--strsize;
}
while ( --minwidth >= strsize ) {
if ( (*put)(padchar) == -1 )
return -1;
++len;
}
}
for ( i=0; i < precision && (c = *strbuf++); ++i ){
if ( (*put)(c) == -1 )
return -1;
}
len += i;
/*
* Pad with blanks, if necessary.
*/
while ( len < minwidth ) {
if ( (*put)(' ') == -1 )
return -1;
++len;
}
nsent += len;
return len;
}
format( psub, ctl, argptr )
int (*psub)(); /* Address of a routine to put a character */
char *ctl; /* The control string. */
char *argptr; /* pointer to arguments */
{
union {
short *hptr;
int *iptr;
long *lptr;
char *cptr;
char **cptr2;
} args;
unsigned int argsize, c;
long l;
char *sptr;
char strbuf[MAXSTRING];
put = psub;
args.cptr = argptr;
nsent = 0;
while ( c = *ctl ) {
/*
* Just print any non '%' characters in control string.
*/
if ( c != '%' ) {
if ( (*psub)(c) == -1 )
return -1;
++ctl;
++nsent;
continue;
}
/*
* Or echo a single '%' for a control string of "%%".
*/
if ( (c = *++ctl) == '%' ) {
if ( (*psub)(c) == -1 )
return -1;
++ctl;
++nsent;
continue;
}
/*
* Start of a format specifier: "%-010.5ld" for example.
*/
rjust = 1;
argsize = sizeof(int);
minwidth = precision = 0;
padchar = ' ';
if ( c == '-' ) {
rjust = 0;
c = *++ctl;
}
if ( c == '0' ) {
padchar = '0';
c = *++ctl;
}
if ( c == '*' ) {
minwidth = *args.iptr++;
c = *++ctl;
} else {
while ( '0' <= c && c <= '9' ) {
minwidth += minwidth * 10 + c - '0';
c = *++ctl;
}
}
if ( c == '.' ) {
c = *++ctl;
if ( c == '*' ) {
precision = *args.iptr++;
c = *++ctl;
} else {
while ( '0' <= c && c <= '9' ){
precision += precision * 10 + c - '0';
c = *++ctl;
}
}
}
if ( c == 'l' || c == 'L' ) {
argsize = sizeof(long);
c = *++ctl;
}
else if ( c == 'h' || c == 'H' ){
argsize = sizeof(short int);
c = *++ctl;
}
/*
* We should be at a conversion specification character.
*/
if ( precision >= (MAXSTRING-2) || precision == 0)
precision = (MAXSTRING-2);
base = 0;
++ctl;
switch(c) {
case 'x': base += 8; /* FALL-THROUGH */
case 'o': base += 8;
case 'd': if ( !base )
base = 10;
if ( argsize == 4 )
l = *args.lptr++;
else
l = *args.hptr++;
sptr = putint( strbuf, l );
if ( prt( sptr ) == -1 )
return -1;
break;
case 's': sptr = *args.cptr2++;
if (minwidth)
precision = minwidth;
else
precision = 32717;
if ( prt( sptr ) == -1 )
return -1;
break;
case 'c': c = *args.iptr++;
default : strbuf[0] = c;
strbuf[1] = '\0';
if ( prt( strbuf ) == -1 )
return -1;
break;
}
}
}